Celem projektu była analiza zbioru danych dotyczącego materiałów wykorzystywanych w bateriach, z wykorzystaniem języka R. Dane te pochodzą z bazy Materials Project – inicjatywy Departamentu Energii USA, która dostarcza otwarte zasoby do badania właściwości i zastosowań materiałów.
Zbiór ten zawiera szczegółowe informacje o składzie chemicznym i parametrach wydajnościowych materiałów stosowanych w bateriach. Analiza pozwala lepiej zrozumieć ich właściwości, co wspiera rozwój innowacyjnych technologii magazynowania energii. Raport przedstawia wyniki przeprowadzonych badań oraz kluczowe wnioski.
Raport przedstawia kompleksową analizę zbioru danych dotyczącego właściwości materiałów do baterii oraz tworzenie modeli predykcyjnych. W pierwszej części dokonano szczegółowej analizy rozkładów poszczególnych atrybutów, co pozwoliło na zrozumienie ich charakterystyki i zidentyfikowanie potencjalnych zależności. Następnie skonstruowano modele predykcyjne dla zmiennych, takich jak energia grawimetryczna oraz średnie napięcie.
Raport zawiera także wizualizacje, które ułatwiają interpretację wyników, oraz metryki oceny modeli, takie jak R-squared, RMSE i MAE, co umożliwia obiektywną ocenę ich skuteczności.
W ramach analizy odkryto, że najczęściej wykorzystywanym jonem głównym jest lit. Zwizualizowano rozkłady atrybutów, pozwalajacę na kompleksową ocenę ich właściwości. Pozwoliło to na odkrycie iż nie ma w zbiorze znacznie dominujących wzorów chemicznych materiału baterii, wykorzystywanych jest wiele unikalnych wzorów. Podsumowano najważniejsze spostrzeżenia charakterystyk materiałów dla różnych grup jonu głównego.
Na podstawie macierzy korelacji wyznaczono atrybuty o największej zależności. Są to energia grawimetryczna i wolumetryczna oraz pojemność grawimetryczna i wolumetryczna. Skonstruowano modele predykcyjne wykorzystując metodę regresji liniowej i random forest. Wstępne dane zostały poddane preprocessingowi opartemu o kilka etapów takich jak usuwanie wartości odstających, normalizacja. Wybrane metryki pozwoliły na ocenę modeli, które wykazały się wysoką jakością predykcji.
library(skimr)
library(corrplot)
library(GGally)
library(dplyr)
library(plotly)
library("Hmisc")
library(mlbench)
library(caret)
library(rlang)
library(knitr)
library(DT)
library(dplyr)
library(ggplot2)
library(gridExtra)
library(here)
library(tidyverse)
library(scales)
library(patchwork)
library(Metrics)
library(broom)
library(randomForest)
urlfile="https://raw.githubusercontent.com/KlaudiaK/Battery-materials-analysis/refs/heads/master/mp_batteries.csv"
data <- read.csv(url(urlfile))
data$Steps <- as.factor(data$Steps)
data$Working.Ion <- as.factor(data$Working.Ion)
data$Formula.Charge <- as.factor(data$Formula.Charge)
data$Formula.Discharge <- as.factor(data$Formula.Discharge)
W celu zilustrowania zawartości zbioru danych, wyświetlono kilka pierwszych wierszy zbioru, aby zaprezentować strukturę tabeli, nazwy zmiennych oraz przykłady wartości, które one przyjmują.
W poniższej tabeli przedstawiono znajdujące się w zbiorze atrybuty oraz ich definicje.
| Atrybut | Opis |
|---|---|
| Battery ID | Identyfikator baterii. |
| Battery Formula | Wzór chemiczny materiału baterii. |
| Working Ion | Główny jon, który odpowiada za transport ładunku w baterii. |
| Formula Charge | Wzór chemiczny materiału baterii w stanie naładowanym. |
| Formula Discharge | Wzór chemiczny materiału baterii w stanie rozładowanym. |
| Max Delta Volume | Zmiana objętości w % dla danego kroku napięcia za pomocą wzoru : max(charge, discharge)/min(charge, discharge) -1. |
| Average Voltage | Średnie napięcie dla poszczególnego kroku napięcia. |
| Gravimetric Capacity | Pojemność grawimetryczna, czyli ilość energii na jednostkę masy (mAh/g). |
| Volumetric Capacity | Pojemność wolumetryczna, czyli ilość energii na jednostkę objętości (mAh/cm³). |
| Gravimetric Energy | Gęstość energii w odniesieniu do masy baterii (Wh/kg). |
| Volumetric Energy | Gęstość energii w odniesieniu do objętości baterii (Wh/L). |
| Atomic Fraction Charge | Udział atomowy składników w stanie naładowanym. |
| Atomic Fraction Discharge | Udział atomowy składników w stanie rozładowanym. |
| Stability Charge | Wskaźnik stabilności materiału w stanie naładowanym. |
| Stability Discharge | Wskaźnik stabilności materiału w stanie rozładowanym. |
| Steps | Liczba odrębnych kroków napięcia od pełnego naładowania do rozładowana, oparta na stabilnych stanach pośrednich. |
| Max Voltage Step | Maksymalna bezwzględna różnica między sąsiednimi krokami napięcia. |
Zbiór danych zawiera 17 atrybutów i 4351 rekordów.
Suma brakujących wartości w zbiorze: 0.
kable(colSums(is.na(data)), col.names = c("Liczba brakujących wartości"), caption = "Liczba brakujących wartości w kolumnach")
| Liczba brakujących wartości | |
|---|---|
| Battery.ID | 0 |
| Battery.Formula | 0 |
| Working.Ion | 0 |
| Formula.Charge | 0 |
| Formula.Discharge | 0 |
| Max.Delta.Volume | 0 |
| Average.Voltage | 0 |
| Gravimetric.Capacity | 0 |
| Volumetric.Capacity | 0 |
| Gravimetric.Energy | 0 |
| Volumetric.Energy | 0 |
| Atomic.Fraction.Charge | 0 |
| Atomic.Fraction.Discharge | 0 |
| Stability.Charge | 0 |
| Stability.Discharge | 0 |
| Steps | 0 |
| Max.Voltage.Step | 0 |
Suma duplikatów: 0.
Zbiór danych nie zawiera brakujących wartości ani duplikatów, więc dane nie wymagają czyszczenia.
skim_summary <- skim(data)
num_character <- skim_summary %>% filter(skim_type == "character") %>% nrow()
num_numeric <- skim_summary %>% filter(skim_type == "numeric") %>% nrow()
num_logical <- skim_summary %>% filter(skim_type == "logical") %>% nrow()
Zbiór zawiera:
- kolumny znakowe: 2,
- kolumny numeryczne: 11,
- kolumny logiczne: 0
skim_summary
── Data Summary ────────────────────────
Values
Name data
Number of rows 4351
Number of columns 17
_______________________
Column type frequency:
character 2
factor 4
numeric 11
________________________
Group variables None
W tej części zostanie przeprowadzona analiza wartości atrybutów w zbiorze danych. Celem tej analizy jest zrozumienie rozkładu, zmienności oraz kluczowych cech poszczególnych atrybutów, co pozwoli na lepszą interpretację danych. Analiza obejmie różne metody wizualizacji, takie jak histogramy, wykresy gęstości oraz wykresy pudełkowe, które umożliwią szybkie wychwycenie istotnych trendów, wartości odstających oraz charakterystyki rozkładu danych.
Sekcja obejmuje wizualizację rozkładów wartości dla atrybutów
numerycznych. W górnej części znajduje się histogram, który ilustruje
częstość występowania różnych wartości atrybutu przyporządkowanych do
określonej liczby przedziałów. Pomarańczowy kolor reprezentuje linię
gęstości rozkładu (tzw. density plot). Wykres gęstości jest używany do
wizualizacji kształtu rozkładu danych, pozwalając na lepsze zrozumienie
jego formy w porównaniu do histogramu. Na wykresie znajduje się również
czerwona linia, oznaczająca średnią wartość atrybutu, oraz zółta
oznaczająca medianę, co pozwala na szybką ocenę jego centralnego
położenia.
Poniżej znajduje się wykres pudełkowy (tzw. boxplot), który wizualizuje
rozproszenie wartości i pozwala na identyfikację wartości
odstających.
for (attr_name in numerical_attrs) {
if (is.numeric(data[[attr_name]])) {
hist_plt <- data %>%
ggplot(mapping = aes_string(x = attr_name)) +
geom_histogram(aes(y = ..density..), bins = 100, fill = "midnightblue", alpha = 0.7) +
geom_density(color = "darkorange", size = 1) +
# Add lines for mean and median
geom_vline(aes(xintercept = mean(get(attr_name), na.rm = TRUE), color = 'Mean'), linetype = "dashed", size = 1.3) +
geom_vline(aes(xintercept = median(get(attr_name), na.rm = TRUE), color = 'Median'), linetype = "dashed", size = 1.3) +
xlab(attr_name) +
ylab("Frequency") +
scale_color_manual(name = "", values = c(Mean = "red", Median = "yellow")) +
theme(legend.position = c(0.9, 0.9), legend.background = element_blank())
box_plt <- data %>%
ggplot(aes_string(x = attr_name, y = 1)) +
geom_boxplot(fill = "#E69F00", color = "gray23", alpha = 0.7) +
xlab(attr_name) +
ylab("")
combined_plot <- (hist_plt / box_plt) +
plot_annotation(title = paste("Distribution of", attr_name),
theme = theme(
plot.title = element_text(hjust = 0.5)))
print(combined_plot)
grid::grid.lines(x = c(0, 1), y = c(0, 0), gp = grid::gpar(col = "black", lty = 2))
} else {
message(paste(attr_name, "is not numeric and will be skipped."))
}
}
NA
NA
Analizując rozkłady zmiennych, można zauważyć kilka kluczowych tendencji. Większość zmiennych charakteryzuje się silnie skośnymi rozkładami z dużą koncentracją wartości blisko zera oraz ogonami wydłużającymi się w kierunku wartości maksymalnych. Takie rozkłady sugerują istnienie znaczącej liczby obserwacji z niskimi wartościami oraz nieliczne przypadki ekstremalnych wyników.
Na histogramach można zauważyć wyraźne piki dla wartości centralnych w niektórych przypadkach, a linie gęstości pomagają uwidocznić kształt tych rozkładów. Średnia (czerwona linia przerywana) i mediana (żółta linia przerywana) często znajdują się bardzo blisko siebie, co wskazuje na umiarkowaną symetrię w części zmiennych. Niemniej jednak, w przypadku niektórych zmiennych, takich jak „Gravimetric.Capacity” czy „Volumetric.Capacity”, różnica między średnią a medianą sugeruje wpływ wartości skrajnych na rozkład.
Wykresy pudełkowe uzupełniają analizę, uwidaczniając obecność licznych wartości odstających w większości zmiennych. Obserwacje odstające są szczególnie widoczne dla zmiennych takich jak „Gravimetric.Energy” czy „Volumetric.Energy”.
Dla poszczególnych atrybutów można wyciągnąć wnioski, że większość wartości koncentruje się w zakresie:
Tabela przedstawia mediany wartości atryburów numerycznych, dla poszczególnych grup głównego jonu transportującego ładunek (Working Ion).
ion_mean_sum <- data %>%
select(Working.Ion, Max.Delta.Volume:Stability.Discharge) %>%
group_by(Working.Ion) %>%
summarise(across(everything(), median))
prettyTable(ion_mean_sum)
data %>%
group_by(Working.Ion) %>%
summarise(total_ion = n()) %>%
ggplot() +
labs(title = paste("Rozkład głównych jonów odpowiadających za transport ładunku w baterii"),
x = "Working.Ion",
y = "Count") +
geom_bar(aes(x = reorder(Working.Ion, total_ion), y = total_ion, fill = Working.Ion), stat = "identity") +
theme_minimal()
Na przedstawionym wykresie zaprezentowano rozkład głównych jonów
używanych do transportu ładunku w bateriach. Wyraźnie dominuje lit (Li),
który występuje znacznie częściej niż inne jony tj. prawie 2500 razy.
Sugeruje to powszechne zastosowanie technologii opartych na
litowo-jonowych rozwiązaniach, co jest zgodne z ich szerokim
wykorzystaniem w przemyśle elektroniki i magazynowania energii.
Szczególną zaletą baterii litowo-jonowych jest wysoką gęstość energii.
To znaczy, że mogą magazynować dużą ilość energii przy niewielkich
rozmiarach i niskiej wadze, co czyni je doskonałym rozwiązaniem dla
przenośnych urządzeń, takich jak laptopy i tablety („Litowo-jonowe a litowo-polimerowe: Szczegółowe
porównanie” 2024). W zestawieniu pierwiastków lit plasuje
się na drugim miejscu pod względem grawimetrcznej gęstości energii,
zaraz za wapniem.
Pozostałe jony, takie jak wapń (Ca), magnez (Mg), i cynk (Zn), również
znajdują zastosowanie, ale w znacznie mniejszym zakresie. Obecność jonów
takich jak sód (Na) i potas (K) mogą wskazywać na badania nad
alternatywami dla litu, jednak ich zastosowanie jest obecnie
ograniczone.
Poniżej znajdują się interaktywne wykresy pudełkowe dla każdej zmiennej numerycznej w zbiorze danych z podziałem na główne jony. Wykresy te umożliwiają eksplorację rozkładu wartości, identyfikację potencjalnych wartości odstających oraz porównanie zmienności w każdej zmiennej dla poszególnych jonów.
for (attr_name in numerical_attrs) {
p <- plot_ly(
data,
y = ~get(attr_name),
type = "box",
boxpoints = "all",
jitter = 0.3,
pointpos = -1.8,
hoverInfo = "text",
color = ~Working.Ion
) %>%
layout(
title = paste("Boxplot of", attr_name),
yaxis = list(title = attr_name)
)
print(p)
}
NA
Wnioski z analizy wykresów rozkładów wartości wybranych atrybutów z podziałem na główny jon:
formula_charge_summary <- data %>%
group_by(Formula.Charge) %>%
summarise(total = n()) %>%
arrange(desc(total))
percentile_99 <- quantile(select(formula_charge_summary, total), probs = 0.99, na.rm = TRUE)
formula_charge_values_99_percentile <- formula_charge_summary %>%
filter(total >= percentile_99)
kable(formula_charge_values_99_percentile)
| Formula.Charge | total |
|---|---|
| MnO2 | 49 |
| TiO2 | 47 |
| VO2 | 46 |
| CrO2 | 45 |
| CoO2 | 43 |
| NiO2 | 41 |
| FeO2 | 36 |
| FePO4 | 26 |
| WO2 | 25 |
| CoPO4 | 24 |
| MnP2O7 | 22 |
| MnPO4 | 22 |
| VF5 | 22 |
| CoP2O7 | 20 |
| FeP2O7 | 20 |
| V2OF5 | 20 |
| WO3 | 20 |
| MoO2 | 19 |
| V2O5 | 19 |
| VPO5 | 18 |
| CrP2O7 | 17 |
| MnFeCo(PO4)3 | 17 |
| VP2O7 | 17 |
formula_charge_values_99_percentile %>%
ggplot() +
labs(title = paste("Wzóry chemiczne materiału baterii w stanie naładowanym"),
x = "Wzór w stanie naładowanym",
y = "Liczba obserwacji") +
geom_bar(aes(x = reorder(Formula.Charge, total), y = total, fill = Formula.Charge), stat = "identity", width = 0.5) +
theme(
text = element_text(size = 12),
axis.text.x = element_text(angle = 90, hjust = 1, size = 8)
)
Wykres przedstawia liczbę wystąpień różnych wzorów chemicznych materiałów baterii w stanie naładowanym. W zbiorze jest 2096 różnych wzorów chemicznych materiałów baterii w stanie naładowanym. Najliczniejszymi są MnO2, TiO2, Vo2, CrO2, NiO2, FeO2.
formula_discharge_summary <- data %>%
group_by(Formula.Discharge) %>%
summarise(total = n()) %>%
arrange(desc(total))
discharge_percentile_99 <- quantile(select(formula_discharge_summary, total), probs = 0.99, na.rm = TRUE)
formula_discharge_values_99_percentile <- formula_discharge_summary %>%
filter(total >= discharge_percentile_99)
formula_discharge_values_99_percentile
formula_discharge_values_99_percentile %>%
ggplot() +
labs(title = paste("Wzóry chemiczne materiału baterii w stanie rozładowanym"),
x = "Wzór w stanie rozładowanym",
y = "Liczba oserwacji") +
geom_bar(aes(x = reorder(Formula.Discharge, total), y = total, fill = Formula.Discharge), stat = "identity", width = 0.5) +
theme(
text = element_text(size = 12),
axis.text.x = element_text(angle = 90, hjust = 1, size = 8),
plot.title = element_text(size = 30)
)
Wykres przedstawia liczbę wystąpień różnych wzorów chemicznych materiałów baterii w stanie rozładowanym. W zbiorze jest 3173 różnych wzorów chemicznych materiałów baterii w stanie rozładowanym. Najczęściej występujące wzory to LiVOF11, Li2O5F5, LiFePO4, LiCoPO4. Znaczna większość najczęściej występujących wzorów zawiera cząsteczkę litu.
Stability Charge
Stability Discharge
summary_stability_charge_working_ion <- data %>%
group_by(Working.Ion) %>%
summarise(stability_charge_mean = mean(Stability.Charge),
stability_charge_median = median(Stability.Charge),
stability_charge_min = min(Stability.Charge),
stability_charge_max = max(Stability.Charge),
total = n()) %>%
arrange(desc(stability_charge_median))
p_stability_charge_working_ion <- ggplot(summary_stability_charge_working_ion, aes(x = total, y = stability_charge_median, color = Working.Ion)) +
geom_point(aes(
text = paste(
"Working Ion:", Working.Ion,
"<br>Median :", round(stability_charge_median, 2),
"<br>Mean :", round(stability_charge_mean, 2),
"<br>Min :", round(stability_charge_min, 2),
"<br>Max :", round(stability_charge_max, 2)
)
), size = 3) +
labs(
title = "Stabilność w stanie naładowanym a główny jon",
x = "Liczba obserwacji",
y = "Wskażnik stabilności w stanie naładowanym"
) +
theme_minimal()
ggplotly(p_stability_charge_working_ion, tooltip = "text")
summary_stability_discharge_working_ion <- data %>%
group_by(Working.Ion) %>%
summarise(stability_discharge_mean = mean(Stability.Discharge),
stability_discharge_median = median(Stability.Discharge),
stability_discharge_min = min(Stability.Discharge),
stability_discharge_max = max(Stability.Discharge),
total = n()) %>%
arrange(desc(stability_discharge_median))
p_stability_discharge_working_ion <- ggplot(summary_stability_discharge_working_ion, aes(x = total, y = stability_discharge_median, color = Working.Ion)) +
geom_point(
aes(
text = paste(
"Working Ion:", Working.Ion,
"<br>Median :", round(stability_discharge_median, 2),
"<br>Mean :", round(stability_discharge_mean, 2),
"<br>Min :", round(stability_discharge_min, 2),
"<br>Max :", round(stability_discharge_max, 2)
)
), size = 3) +
labs(
title = "Stabilność w stanie rozładowanym a główny jon",
x = "Liczba obserwacji",
y = "Wskażnik stabilności w stanie rozładowanym"
) +
theme_minimal()
ggplotly(p_stability_discharge_working_ion, tooltip = "text")
Stabilność w stanie naładowanym:
Stabilność w stanie rozładowanym:
Szczególną uwagę przyciąga lit, który charakteryzuje się największą liczbą obserwacji i jednocześnie zajmuje pośrednie miejsce w zestawieniu pod względem wartości wskaźników stabilności.
summary_max_data_volume_working_ion <- data %>%
group_by(Working.Ion) %>%
summarise(max_data_volume_mean = mean(Max.Delta.Volume),
max_data_volume_median = median(Max.Delta.Volume),
max_data_volume_min = min(Max.Delta.Volume),
max_data_volume_max = max(Max.Delta.Volume),
total = n()) %>%
arrange(max_data_volume_mean)
prettyTable(summary_max_data_volume_working_ion)
p <- ggplot(summary_max_data_volume_working_ion, aes(x = total, y = max_data_volume_median, color = Working.Ion)) +
geom_point(aes(
text = paste(
"Working Ion:", Working.Ion,
"<br>Median :", round(max_data_volume_median, 2),
"<br>Mean :", round(max_data_volume_mean, 2),
"<br>Min :", round(max_data_volume_min, 2),
"<br>Max :", round(max_data_volume_max, 2)
)
), size = 3, alpha = 0.7) +
labs(
title = "Mediana zmiany objętości w % dla danego kroku napięcia dla jonów głównych",
x = "Liczba obserwacji",
y = "Mediana maksymalnej zmiany objętości"
) +
theme_minimal() +
theme(legend.position = "bottom")
ggplotly(p, tooltip = "text")
Najniższą zmianą napięcia charakteryzuje się lit (Li), a najwyższą itr (Y).
Gęstość Grawimetryczna
summary_gravimetric_energy_working_ion <- data %>%
group_by(Working.Ion) %>%
summarise(gravimetric_energy_mean = mean(Gravimetric.Energy),
gravimetric_energy_median = median(Gravimetric.Energy),,
gravimetric_energy_min = min(Gravimetric.Energy),
gravimetric_energy_max = max(Gravimetric.Energy),
total = n()) %>%
arrange(desc(gravimetric_energy_median))
prettyTable(summary_gravimetric_energy_working_ion)
p <- ggplot(summary_gravimetric_energy_working_ion, aes(x = total, y = gravimetric_energy_median, color = Working.Ion)) +
geom_point(aes(
text = paste(
"Working Ion:", Working.Ion,
"<br>Median :", round(gravimetric_energy_median, 2),
"<br>Mean :", round(gravimetric_energy_mean, 2),
"<br>Min :", round(gravimetric_energy_min, 2),
"<br>Max :", round(gravimetric_energy_max, 2)
)
), size = 3, alpha = 0.7) +
labs(
title = "Mediana energii grawimetrycznej dla jonów głównych",
x = "Liczba obserwacji",
y = "Mediana energii grawimetrycznej"
) +
theme_minimal() +
theme(legend.position = "bottom")
ggplotly(p, tooltip = "text")
NA
NA
Pojemność Grawimetryczna
summary_gravimetric_capacity_working_ion <- data %>%
group_by(Working.Ion) %>%
summarise(gravimetric_capacity_mean = mean(Gravimetric.Capacity),
gravimetric_capacity_median = median(Gravimetric.Capacity),
gravimetric_capacity_min = min(Gravimetric.Capacity),
gravimetric_capacity_max = max(Gravimetric.Capacity),
total = n()) %>%
arrange(desc(gravimetric_capacity_median))
prettyTable(summary_gravimetric_capacity_working_ion)
p <- ggplot(summary_gravimetric_capacity_working_ion, aes(x = total, y = gravimetric_capacity_median, color = Working.Ion)) +
geom_point(aes(
text = paste(
"Working Ion:", Working.Ion,
"<br>Median :", round(gravimetric_capacity_median, 2),
"<br>Mean :", round(gravimetric_capacity_mean, 2),
"<br>Min :", round(gravimetric_capacity_min, 2),
"<br>Max :", round(gravimetric_capacity_max, 2)
)
), size = 3, alpha = 0.7) +
labs(
title = "Mediana pojemności grawimetrycznej dla głównych jonów",
x = "Liczba obserwacji",
y = "Mediana pojemności grawimetrycznej"
) +
theme_minimal() +
theme(legend.position = "bottom")
ggplotly(p, tooltip = "text")
NA
Zarówno rubid (Rb) jak i cez (Cs), które wypadają najgorzej pod względem energii i gestości grawimetrycznej są najrzadziej wykorzystywanymi jonami głównymi.
Poniższy wykres przedstawia zależność między liczbą obserwacji dla najczęściej występujących Wzorów chemicznych materiałów baterii w stanie naładowanym a medianą stabilności w stanie naładowanym. Dla każdego wzoru obliczono miary statyczne, które wyświetlają się po najechaniu na punkt.
formula_charge_summary <- data %>%
group_by(Formula.Charge) %>%
summarise(total = n()) %>%
arrange(desc(total))
percentile_99 <- quantile(select(formula_charge_summary, total), probs = 0.99, na.rm = TRUE)
formula_charge_values_99_percentile <- formula_charge_summary %>%
filter(total >= percentile_99)
summary_data <- data %>%
filter(Formula.Charge %in% formula_charge_values_99_percentile$Formula.Charge) %>%
group_by(Formula.Charge) %>%
summarise(total = n(),
stability_charge_mean = mean(Stability.Charge),
stability_charge_median = median(Stability.Charge),
stability_charge_min = min(Stability.Charge),
stability_charge_max = max(Stability.Charge)) %>%
arrange(desc(total))
p <- ggplot(summary_data, aes(x = total, y = stability_charge_median)) +
geom_point(aes(
text = paste(
"Formula charge:", Formula.Charge,
"<br>Stability charge median:", round(stability_charge_median, 4),
"<br>Stability charge mean:", round(stability_charge_mean, 4),
"<br>Min Stability:", round(stability_charge_min, 4),
"<br>Max Stability:", round(stability_charge_max, 4)
),
size = total, color = stability_charge_median
), alpha = 0.7) +
scale_color_gradient(low = "blue", high = "red") +
scale_size_continuous(range = c(2, 10)) +
labs(
title = "Mediana stabilności w stanie naładowanym <br>dla najczęstszych wzorów chemicznych materiałów baterii",
x = "Liczba obserwacji",
y = "Mediana stabilności w stanie naładowanym"
) +
theme_minimal() +
theme(
legend.position = "bottom",
plot.title = element_text(hjust = 0.5)
)
ggplotly(p, tooltip = "text")
NA
Poniższa macierz korelacji ilustruje współczynniki korelacji Pearsona dla wybranych atrybutów. Kolory kafelków reprezentują siłę oraz kierunek korelacji. Odcienie niebieskiego wskazują na dodatnią korelację, a odcienie czerwonego na ujemną.
number_attr_data <- select(data, (numerical_attrs))
cor_matrix <- cor(number_attr_data, method = "pearson")
corrplot.mixed(cor_matrix,
tl.pos = 'lt',
order = 'AOE',
lower = 'shade',
upper = 'number'
)
Najwyższy wspolczynnik korelacji wystepuje pomiedzy
parami atrybutów:
- Gravimetric Energy i Volumetric Energy - 0.93
- Gravimetric Capcity i Volumetric Capacity -
0.86
- Stability Charge i Stability Discharge - 0.80
- Gravimetric Capacity i Atomic Fraction Discharge - 0.68
- Average Voltage i Gravimetric Energy - 0.67
gravimetric_volumetric_energy_correlation <- cor(data$Gravimetric.Energy, data$Volumetric.Energy, use = "complete.obs")
ggplot(data, aes(x = Gravimetric.Energy, y = Volumetric.Energy)) +
geom_point(color = "darkgreen", size = 2, alpha = 0.7) +
geom_smooth(method = "lm", color = "blue", se = FALSE, linetype = "dashed") +
geom_smooth(method = "loess", color = "red", se = TRUE, fill = "gray80") +
labs(title = "Korelacja między grawimetryczną i wolumetryczną gęstością energii",
subtitle = paste("Współczynnik korelacji =", round(gravimetric_volumetric_energy_correlation, 2)),
x = "Grawimetryczna gęstość energii (Wh/kg)",
y = "Wolumetryczna gęstość energii (Wh/L)") +
theme_minimal()
Wykres przedstawia zależność między wolumetryczną (Wh/L, energia na jednostkę objętości) i grawimetryczną (Wh/kg, energia na jednostkę masy) gęstością energii, gdzie widoczna jest silna korelacja dodatnia między tymi parametrami. Gęstość energii jest kluczowym wskaźnikiem wydajności baterii - im wyższa wartość, tym więcej energii może być zmagazynowane w danej objętości lub masie baterii, co jest szczególnie istotne w zastosowaniach mobilnych, takich jak pojazdy elektryczne czy urządzenia przenośne. Większość badanych materiałów skupia się w zakresie do 2000 Wh/kg i 7500 Wh/L, choć występuje kilka obiecujących wyjątków o wyższych parametrach, które mogą stanowić potencjalne kierunki rozwoju nowych, wydajniejszych baterii.
gravimetric_volumetric_capacity_correlation <- cor(data$Gravimetric.Capacity, data$Volumetric.Capacity, use = "complete.obs")
ggplot(data, aes(x = Gravimetric.Capacity, y = Volumetric.Capacity)) +
geom_point(color = "darkgreen", size = 2, alpha = 0.7) +
geom_smooth(method = "lm", color = "blue", se = FALSE) +
geom_smooth(method = "loess", color = "red", se = TRUE, fill = "gray80") +
labs(title = "Korelacja między grawimetryczną i wolumetryczną pojemnością ",
subtitle = paste("Correlation =", round(gravimetric_volumetric_capacity_correlation, 2)),
x = "Pojemność grawimetryczna (mAh/g)",
y = "Pojemność wolumetryczna (mAh/cm³)") +
theme_minimal()
Wykres przedstawia zależność między wolumetryczną (mAh/cm³, ilość ładunku na jednostkę objętości) i grawimetryczną (mAh/g, ilość ładunku na jednostkę masy) pojemnością. Pojemność grawimetryczna określa ile energii można zmagazynować w danej masie materiału, a wolumetryczna - ile w danej objętości, co ma kluczowe znaczenie przy projektowaniu baterii o różnym przeznaczeniu. Współczynnik korelacji 0.86 wskazuje na silną zależność między tymi parametrami, choć nie tak silną jak w przypadku gęstości energii. Na przykład, materiał o wysokiej pojemności grawimetrycznej może być lekki, ale zajmować dużo miejsca, podczas gdy materiał o wysokiej pojemności wolumetrycznej może być cięższy, ale bardziej kompaktowy („Co warto wiedzieć o ogniwach litowo‑jonowych?” 2024).
stability_charge_discharge_coorelation <- cor(data$Stability.Charge, data$Stability.Discharge, use = "complete.obs")
ggplot(data, aes(x = Stability.Charge, y = Stability.Discharge)) +
geom_point(color = "darkgreen", size = 2, alpha = 0.7) +
geom_smooth(method = "lm", color = "blue", se = FALSE, linetype = "dashed") +
geom_smooth(method = "loess", color = "red", se = TRUE, fill = "gray80") +
labs(title = "Korelacja materiału w stanie naładowanym i rozładowanym",
subtitle = paste("Correlation =", round(stability_charge_discharge_coorelation, 2)),
x = "Stabilność w stanie naładowanym",
y = "Stabilność w stanie rozładowanym") +
theme_minimal()
Wykres przedstawia zależność między stabilnością materiału w stanie naładowanym (Stability Charge) i w stanie rozładowanym (Stability Discharge), ze współczynnikiem korelacji 0.8 wskazującym na silną dodatnią zależność. Stabilność materiału jest kluczowym parametrem określającym, jak dobrze materiał zachowuje swoją strukturę i właściwości podczas cykli ładowania i rozładowania - im niższa wartość, tym materiał jest bardziej stabilny i bezpieczny w użytkowaniu. Większość badanych materiałów skupia się w zakresie niskich wartości (0-2) dla obu parametrów, co jest pożądane, natomiast punkty odstające o wyższych wartościach (powyżej 4) mogą wskazywać na materiały problematyczne, które mogą być mniej odpowiednie do zastosowań w bateriach ze względu na potencjalną niestabilność.
gravimetric_capacity_atomic_fraction_discharge_coorelation <- cor(data$Gravimetric.Capacity, data$Atomic.Fraction.Discharge, use = "complete.obs")
ggplot(data, aes(x = Gravimetric.Capacity, y = Atomic.Fraction.Discharge)) +
geom_point(aes(color = Atomic.Fraction.Discharge), size = 3, alpha = 0.7) +
geom_smooth(method = "loess", color = "red", se = TRUE, fill = "gray80") +
labs(title = "Korelacja między pojemnnością grawimetryczną a udział atomowym składników w stanie rozładowanym",
subtitle = paste("Correlation =", round(gravimetric_capacity_atomic_fraction_discharge_coorelation, 2)),
x = "Pojemność grawimetryczna (mAh/g)",
y = "Udział atomowy składników w stanie rozładowanym.") +
scale_color_gradient(low = "orange", high = "purple") +
theme_minimal()
Wykres przedstawia zależność między pojemnością
grawimetryczną (Gravimetric Capacity, mAh/g) i udziałem
atomowym w stanie rozładowania (Atomic Fraction Discharge).
Można zaobserwować umiarkowanie silną dodatnią zależność, co potwierdza
współczynnik korelacji wynoszący 0.68. W miarę wzrostu pojemności
grawimetrycznej, udział atomowy w stanie rozładowania zwiększa się,
osiągając wartość maksymalną bliską 1.0.
Kolor punktów reprezentuje wartość Atomic Fraction Discharge, gdzie
jaśniejsze kolory wskazują na niższe wartości, a ciemniejsze na wyższe.
Dane wskazują, że większość obserwacji znajduje się w zakresie niskiej
pojemności grawimetrycznej (<1000 mAh/g), a dla wartości powyżej 2000
mAh/g zależność staje się nieliniowa. Sugeruje to, że materiały o
wyższej pojemności grawimetrycznej mają tendencję do osiągania wyższych
udziałów atomowych w stanie rozładowania.
filteredData <- data %>%filter(data$Steps == 3)
correlation <- cor(data$Average.Voltage, data$Gravimetric.Energy, use = "complete.obs")
ggplot(data, aes(x = Average.Voltage, y = Gravimetric.Energy)) +
geom_point(color = "darkblue", size = 3, alpha = 0.7) +
geom_smooth(method = "lm", color = "darkred", se = FALSE, linetype = "dashed") +
labs(title = "Korelacja między średnim napięciem i energią grawimetryczną",
subtitle = paste("Correlation =", round(correlation, 2)),
x = "Średnie napięcie (V)",
y = "Energia grawimetryczna (Wh/kg)") +
theme_classic()
data_with_cor <- data %>%
group_by(Steps) %>%
summarise(
correlation = cor(Average.Voltage, Gravimetric.Energy, use = "complete.obs"),
n_cases = n()
)
p <- ggplot(data, aes(x = Average.Voltage, y = Gravimetric.Energy)) +
geom_point(aes(text = paste("Step:", Steps,
"<br>Voltage:", Average.Voltage,
"<br>Energy:", Gravimetric.Energy,
"<br>Ion:", Working.Ion)),
color = "darkblue", size = 3, alpha = 0.7) +
geom_smooth(method = "lm", color = "darkred", se = FALSE, linetype = "dashed") +
facet_wrap(~ Steps, scales = "fixed", ncol = 2,
labeller = labeller(Steps = function(x) {
row <- data_with_cor[data_with_cor$Steps == x, ]
paste0("Step = ", x, " (Corr = ", round(row$correlation, 2),
", n = ", row$n_cases, ")")
})) +
labs(title = "Średnie napięcie a energia grawimetryczna przy uwzględnieniu wartości kroku",
x = "Średnie napięcie (V)",
y = "Energia grawimetryczna (Wh/kg)") +
theme_grey() +
theme(
plot.title = element_text(margin = ggplot2::margin(t = 10, b = 10), hjust = 0.5),
axis.title.x = element_text(margin = ggplot2::margin(t = 10)),
axis.title.y = element_text(margin = ggplot2::margin(r = 10)),
plot.margin = ggplot2::margin(20, 20, 20, 20),
panel.spacing = unit(2, "cm")
)
ggplotly(p, tooltip = "text")
Wykresy przedstawiają zależności między średnim napięciem (Average Voltage, V) a gęstością energii grawimetrycznej (Gravimetric Energy Density, Wh/kg) dla różnych wartości kroku napięcia. Najwięcej obserwacji jest dla kroku równego 1 i jest to najbardziej reprezentatywna próbka. W tym przypadku współczynnik korelacji jest na wysokim poziomie, bo wynosi 0.69. Dane wskazują, że wraz ze wzrostem średniego napięcia zwiększa się gęstość energii grawimetrycznej. Większość danych skupia się w zakresie niskich wartości napięcia (<10 V), co sugeruje, że materiały o wyższym napięciu są mniej liczne, ale mogą wykazywać większą efektywność energetyczną.
W tej sekcji zostaną przeanalizowane dwa modele predykcyjne dotyczące właściwości baterii. Pierwszy model, oparty na regresji liniowej, skupia się na przewidywaniu energii grawimetrycznej. Drugi model, wykorzystujący algorytm Random Forest, przewiduje średnie napięcie. W obu przypadkach celem jest ocena skuteczności zastosowanych metod oraz identyfikacja kluczowych czynników wpływających na wyniki.
Preprocessing danych jest kluczowym etapem przygotowania zbioru treningowego, ponieważ wpływa bezpośrednio na jakość, precyzję i zdolność predykcyjną modelu, eliminując szumy, redundancje i potencjalne źródła błędów, co ostatecznie decyduje o skuteczności i wiarygodności całego modelu.
attributes_to_remove <- colnames(select(data, c(Battery.ID, Battery.Formula, Formula.Discharge)))
W pierwszym kroku usunięto wybrane kolumny takie jak Battery.ID, Battery.Formula, Formula.Discharge, które nie wnosiły bezpośrednich informacji numerycznych do modelowania.
battery_train_data <- select(data, -(attributes_to_remove))
cor_thereshold <- 0.8
cor_with_target <- cor(dataset_numerical_attrs, use = "pairwise.complete.obs")[, "Volumetric.Energy"]
high_cor_to_target <- names(which(cor_with_target > 0.8))
battery_train_data <- battery_train_data %>%
select(-all_of(high_cor_to_target), Volumetric.Energy)
Następnie, obliczono korelację zmiennych numerycznych ze zmienną celu, zidentyfikowano i usunięto zmienne o wysokiej korelacji liniowej (przekraczającej wartość 0.8). Atrybuty, które zostały usunięte to Average.Voltage.
outlier_threshold <- 2
detect_outliers <- function(x) {
Q1 <- quantile(x, 0.25, na.rm = TRUE)
Q3 <- quantile(x, 0.75, na.rm = TRUE)
IQR <- Q3 - Q1
return(x < (Q1 - 1.5 * IQR) | x > (Q3 + 1.5 * IQR))
}
outlier_matrix <- as.data.frame(lapply(battery_train_data, function(column) {
if (is.numeric(column)) {
return(detect_outliers(column))
} else {
return(rep(FALSE, length(column)))
}
}))
outlier_count <- rowSums(outlier_matrix)
nrow(battery_train_data[outlier_count >= outlier_threshold,])
[1] 716
data_cleaned <- battery_train_data[outlier_count < outlier_threshold, ]
skim(data_cleaned)
── Data Summary ────────────────────────
Values
Name data_cleaned
Number of rows 3635
Number of columns 13
_______________________
Column type frequency:
factor 3
numeric 10
________________________
Group variables None
W procesie preprocessingu danych jednym z kluczowych etapów była identyfikacja i usunięcie obserwacji odstających w zbiorze danych. W tym celu zdefiniowano próg dla liczby odstających wartości w danej obserwacji (outlier_threshold), który ustalono na poziomie 2. Następnie, wykorzystując metodę opartą na analizie rozstępu międzykwartylowego (IQR), zidentyfikowano wartości odstające w każdej kolumnie numerycznej zbioru danych.
Funkcja ta oblicza pierwszy (Q1) i trzeci kwartyl (Q3) dla każdej zmiennej, a następnie określa zakres wartości uznawanych za normalne, wyznaczony przez przedział [Q1−1.5⋅IQR,Q3+1.5⋅IQR]. Wartości spoza tego zakresu są oznaczane jako odstające. Na tej podstawie wygenerowano macierz logiczną, gdzie każda komórka wskazuje, czy dana wartość w zbiorze danych jest odstająca.
Dla każdej obserwacji w zbiorze danych policzono następnie liczbę odstających wartości. Obserwacje zawierające co najmniej dwie wartości odstające (zgodnie z ustalonym progiem) zostały oznaczone jako potencjalnie problematyczne. Takie obserwacje zostały wykluczone z dalszej analizy, co pozwoliło oczyścić dane i zminimalizować ich wpływ na model. Zostało usuniętych 318 rekordów.
data_scaled <- as.data.frame(lapply(data_cleaned, function(col) {
if (is.numeric(col)) {
rescale(col)
} else {
col
}
}))
skim(data_scaled)
── Data Summary ────────────────────────
Values
Name data_scaled
Number of rows 3635
Number of columns 13
_______________________
Column type frequency:
factor 3
numeric 10
________________________
Group variables None
Następnie dane zostały znormalizowane, do czego wykorzystano funkcję rescale.
Dane zostały podzielone na zbiory treningowy (70%) i testowy (30%). Podczas trenowania modelu zastosowano metodę walidacji krzyżowej, aby zapewnić jego stabilność i uogólnioną jakość. Dodatkowo, aby upewnić się, że rozkłady zmiennej celu są podobne w obu zbiorach, zwizualizowano je na poniższym wykresie gęstości.
idx <- createDataPartition(data_scaled$Volumetric.Energy, p=0.7, list=F)
train_data <- data_scaled[idx, ]
test_data <- data_scaled[-idx, ]
ctrl <- trainControl(method = "cv", number = 10)
ggplot(mapping = aes(alpha = 0.4)) +
geom_density(aes(x = Volumetric.Energy, fill = "red"), data = train_data) +
geom_density(aes(x = Volumetric.Energy, fill = "blue"), data = test_data) +
theme_minimal()
model<- lm(
Volumetric.Energy~.,
data = train_data,
trControl = ctrl
)
Do oceny modelu wybrano metryki R-squared, R-squared adjusted oraz RMSE. Model osiąga bardzo wysokie dopasowanie, wyjaśniając 97,57% zmienności zmiennej zależnej (R-squared). Skorygowana wartość (R-squared adjusted) wynosząca 94,46% uwzględnia liczbę predyktorów, co wskazuje na wysoką jakość modelu przy minimalnym wpływie nadmiernego dopasowania. Niska wartość RMSE (0,1788) potwierdza, że średni błąd predykcji jest niewielki w kontekście skali zmiennej zależnej, co świadczy o dużej dokładności modelu. Model jest dobrze dopasowany i precyzyjny.
model_summary <- summary(model)
rmse_value <- rmse(test_data$Volumetric.Energy, predictions)
results <- data.frame(
Metryka = c("R-squared", "R-squared adjusted", "RMSE"),
Wartość = c(
model_summary$r.squared,
model_summary$adj.r.squared,
round(rmse_value, 4)
)
)
kable(
results,
col.names = c("Metryka", "Wartość"),
align = "c",
caption = "Wyniki modelu"
)
| Metryka | Wartość |
|---|---|
| R-squared | 0.9757357 |
| R-squared adjusted | 0.9445946 |
| RMSE | 3.1208000 |
NA
coefficients <- tidy(model)
residuals <- resid(model)
fitted <- fitted(model)
residuals_fitted_plot <- ggplot(data = data.frame(residuals, fitted), aes(x = fitted, y = residuals)) +
geom_point(alpha = 0.6, color = "blue") +
geom_hline(yintercept = 0, linetype = "dashed", color = "red") +
labs(title = "Reszty a dopasowane wartości", x = "Dopasowane wartości", y = "Reszty") +
theme_minimal()
qq_plot <- ggplot(data = data.frame(residuals), aes(sample = residuals)) +
stat_qq(color = "blue", alpha = 0.6) +
stat_qq_line(color = "red") +
labs(title = "Wykres Q-Q dla reszt", x = "Teoretyczne kwantyle", y = "Kwantyle próby") +
theme_minimal()
residuals_hist <- ggplot(data = data.frame(residuals), aes(x = residuals)) +
geom_histogram(aes(y = ..density..), bins = 30, fill = "blue", alpha = 0.6) +
geom_density(color = "red", size = 1) +
labs(title = "Histogram reszt", x = "Reszty", y = "Gęstość") +
theme_minimal()
predictions <- predict(model, newdata = train_data)
observed <- train_data$Volumetric.Energy
observed_predicted_plot <- ggplot(data = data.frame(observed, predictions), aes(x = observed, y = predictions)) +
geom_point(alpha = 0.6, color = "blue") +
geom_abline(intercept = 0, slope = 1, linetype = "dashed", color = "red") +
labs(title = "Rzeczywiste a przewidywane wartości", x = "Rzeczywiste", y = "Przewidywane") +
theme_minimal()
grid.arrange(residuals_fitted_plot, qq_plot, residuals_hist, observed_predicted_plot, ncol = 2)
Reszty są równomiernie rozproszone wokół poziomej linii, a ich rozkład nie wykazuje żadnych wyraźnych wzorców czy tendencji. Sugeruje to, że założenie liniowości modelu jest spełnione i świadczy o poprawnej specyfikacji modelu. Dodatkowo, wykres Q-Q dla reszt wykazuje, iż rozkład ten jest zbliżony do normalnego, potwierdzając tym samym kolejne ważne założenie regresji. Histogram reszt również potwierdza ten wniosek, prezentując symetryczny kształt typowy dla rozkładu normalnego. Kluczowym elementem oceny jakości modelu jest wykres porównujący wartości rzeczywiste i przewidywane, który pokazuje, że predykcje modelu ściśle odpowiadają rzeczywistym obserwacjom - punkty układają się wzdłuż linii o nachyleniu zbliżonym do 1, co świadczy o dobrym dopasowaniu modelu. Nieznaczne odchylenia od linii idealnej są normalne i wynikają z występowania reszt, które nie zostały w pełni wytłumaczone przez model.
coefficients <- summary(model)$coefficients
coefficients_sorted <- coefficients[order(abs(coefficients[, "Estimate"]), decreasing = TRUE), ]
datatable(coefficients_sorted,
options = list(pageLength = 10,
autoWidth = TRUE,
searchHighlight = TRUE))
importance <- varImp(model)
sorted_attr_importance <- importance %>%
arrange(desc(Overall))
sorted_attr_importance
W rozdziale zostanie przeanalizowana predykcja średniego napięcia (Average Voltage) przy użyciu modelu Random Forest. Model ten pozwala uchwycić nieliniowe zależności i zidentyfikować kluczowe czynniki wpływające na napięcie. Przedstawione zostaną miary jakości oraz znaczenie zmiennych.
attributes_to_remove_rf <- colnames(select(data, c(Battery.ID, Battery.Formula, Formula.Discharge, Formula.Charge)))
W pierwszym kroku usunięto wybrane kolumny takie jak Battery.ID, Battery.Formula, Formula.Discharge, Formula.Charge, które nie wnosiły bezpośrednich informacji do modelowania.
train_data_rf <- select(data, -(attributes_to_remove_rf))
cor_thereshold <- 0.8
cor_with_target <- cor(dataset_numerical_attrs, use = "pairwise.complete.obs")[, "Average.Voltage"]
high_cor_to_target <- names(which(cor_with_target > 0.8))
train_data_rf <- train_data_rf %>%
select(-all_of(high_cor_to_target), Average.Voltage)
Następnie, obliczono korelację zmiennych numerycznych ze zmienną celu, zidentyfikowano i usunięto zmienne o wysokiej korelacji liniowej (przekraczającej wartość 0.8). Atrybuty, które zostały usunięte to Average.Voltage.
outlier_threshold <- 3
outlier_matrix <- as.data.frame(lapply(train_data_rf, function(column) {
if (is.numeric(column)) {
return(detect_outliers(column))
} else {
return(rep(FALSE, length(column)))
}
}))
outlier_count <- rowSums(outlier_matrix)
removed_attrs <- nrow(train_data_rf[outlier_count >= outlier_threshold,])
data_cleaned_rf <- train_data_rf[outlier_count < outlier_threshold, ]
skim(data_cleaned_rf)
── Data Summary ────────────────────────
Values
Name data_cleaned_rf
Number of rows 4033
Number of columns 13
_______________________
Column type frequency:
factor 2
numeric 11
________________________
Group variables None
Ze zbioru usunięto 318 rekordów.
data_rf <- train_data_rf
head(data_rf)
idx_rf <- createDataPartition(data_rf$Average.Voltage, p=0.7, list=F)
train_data_rf <- data_rf[idx, ]
test_data_rf <- data_rf[-idx, ]
ctrl <- trainControl(method = "cv", number = 10)
ggplot(mapping = aes(alpha = 0.4)) +
geom_density(aes(x = Average.Voltage, fill = "red"), data = train_data_rf) +
geom_density(aes(x = Average.Voltage, fill = "blue"), data = test_data_rf) +
theme_minimal()
Zbiory mają zbliżone rozkłady zmiennej celu.
model_rf <- train(
Average.Voltage ~.,
data = train_data_rf,
method = "rf",
metric = "RMSE",
trControl = ctrl,
tuneGrid = expand.grid(mtry=3)
)
predictions <- predict(model_rf, newdata = test_data_rf)
W celu oceny jakości modeli wykorzystano metryki RMSE, R-squared i MAE, ponieważ umożliwiają one kompleksową analizę błędów predykcji oraz dopasowania modelu do danych.
ggplot(data.frame(Actual = test_data_rf$Average.Voltage, Predicted = predictions), aes(x = Actual, y = Predicted)) +
geom_point(alpha = 0.6, color = "blue") +
geom_abline(slope = 1, intercept = 0, color = "red") +
labs(title = "Wartości rzeczywiste a predykcja", x = "Rzeczywiste", y = "Przewidywane")
results <- data.frame(
Metryka = c("RMSE", "R-squared", "MAE"),
Wartość = c(
model_rf$results$RMSE,
model_rf$results$Rsquared,
model_rf$results$MAE
)
)
kable(
results,
col.names = c("Metryka", "Wartość"),
align = "c",
caption = "Wyniki modelu Random Forest"
)
| Metryka | Wartość |
|---|---|
| RMSE | 0.5308909 |
| R-squared | 0.8949949 |
| MAE | 0.3789240 |
RMSE wskazuje, że przeciętny błąd predykcji wynosi około 0.53. Atrybut przyjmuje wartości z przedziału (-7;5.5), a więc RMSE jest stosunkowo niski. Sugeruje to, że model dobrze przewiduje wartość napięcia w większości przypadków, przy umiarkowanym błędzie. Wartość \(R^2 = 0.894\) oznacza, że model wyjaśnia 89.4% zmienności zmiennej zależnej. Jest to bardzo dobry wynik, wskazujący, że model dobrze dopasowuje się do danych i większość obserwacji może być przewidziana na podstawie dostępnych cech.
importance_df <- variable_importance$importance %>%
as.data.frame() %>%
tibble::rownames_to_column(var = "Variable") %>%
arrange(desc(Overall))
ggplot(importance_df, aes(x = reorder(Variable, Overall), y = Overall)) +
geom_bar(stat = "identity", fill = "steelblue", alpha = 0.8) +
coord_flip() +
labs(
title = "Ważność zmiennych (Random Forest)",
x = "Zmienna",
y = "Znaczenie (Overall)"
) +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, size = 16, face = "bold"),
axis.title = element_text(size = 14),
axis.text = element_text(size = 12)
)
Najbardziej istotne zmienne dla predykcji modelu to energia grawimetryczna i wolumetryczna.